package com.kurt.service.impl;

import com.kurt.dto.DataPermissionDTO;
import com.kurt.dto.create.DataPermissionCreateRequest;
import com.kurt.dto.query.DataPermissionQueryRequest;
import com.kurt.entity.SysUser;
import com.kurt.entity.SysUserDataPermission;
import com.kurt.repository.SysUserDataPermissionRepository;
import com.kurt.repository.SysUserRepository;
import com.kurt.service.DataPermissionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 数据权限服务实现类
 * 实现数据权限相关的业务逻辑
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DataPermissionServiceImpl extends BaseServiceImpl<SysUserDataPermission, Long> implements DataPermissionService {

    private final SysUserDataPermissionRepository dataPermissionRepository;
    private final SysUserRepository userRepository;

    @Override
    protected SysUserDataPermissionRepository getRepository() {
        return dataPermissionRepository;
    }

    @Override
    protected SysUserDataPermissionRepository getSpecificationExecutor() {
        return dataPermissionRepository;
    }

    @Override
    @Transactional
    public DataPermissionDTO createDataPermission(DataPermissionCreateRequest createRequest) {
        log.info("创建数据权限: userId={}, entityType={}, resourceId={}",
                createRequest.getUserId(), createRequest.getEntityType(),
                createRequest.getResourceId());

        // 检查权限是否已存在
        if (dataPermissionRepository.existsByUserIdAndEntityTypeAndResourceId(
                createRequest.getUserId(), createRequest.getEntityType(),
                createRequest.getResourceId())) {
            throw new RuntimeException("数据权限已存在");
        }

        // 创建数据权限实体
        SysUserDataPermission dataPermission = new SysUserDataPermission();
        BeanUtils.copyProperties(createRequest, dataPermission);
        dataPermission.setCreateTime(LocalDateTime.now());
        dataPermission.setCreateUserId(createRequest.getUserId()); // 简化处理，使用当前用户ID

        // 保存数据权限
        dataPermission = dataPermissionRepository.save(dataPermission);

        log.info("数据权限创建成功: {}", dataPermission.getId());
        return convertToDataPermissionDTO(dataPermission);
    }


    @Override
    public DataPermissionDTO getDataPermissionById(Long id) {
        SysUserDataPermission dataPermission = getById(id);
        return convertToDataPermissionDTO(dataPermission);
    }

    @Override
    public Page<DataPermissionDTO> getDataPermissionPage(DataPermissionQueryRequest queryRequest) {
        // 构建分页参数
        Sort sort = Sort.by(Sort.Direction.fromString(queryRequest.getOrderDirection()), queryRequest.getOrderBy());
        Pageable pageable = PageRequest.of(queryRequest.getPageNum() - 1, queryRequest.getPageSize(), sort);

        // 构建查询条件
        Specification<SysUserDataPermission> spec = buildDataPermissionSpecification(queryRequest);

        // 执行分页查询
        Page<SysUserDataPermission> dataPermissionPage = dataPermissionRepository.findAll(spec, pageable);

        // 转换为DTO
        return dataPermissionPage.map(this::convertToDataPermissionDTO);
    }

    @Override
    public List<DataPermissionDTO> getDataPermissionList(DataPermissionQueryRequest queryRequest) {
        // 构建查询条件
        Specification<SysUserDataPermission> spec = buildDataPermissionSpecification(queryRequest);

        // 执行查询
        List<SysUserDataPermission> dataPermissions = dataPermissionRepository.findAll(spec);

        // 转换为DTO
        return dataPermissions.stream().map(this::convertToDataPermissionDTO).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean deleteDataPermission(Long id) {
        log.info("删除数据权限: {}", id);

        dataPermissionRepository.deleteById(id);

        log.info("数据权限删除成功: {}", id);
        return true;
    }

    @Override
    @Transactional
    public boolean deleteDataPermissions(List<Long> ids) {
        log.info("批量删除数据权限: {}", ids);

        dataPermissionRepository.deleteAllById(ids);

        log.info("批量删除数据权限成功: {}", ids);
        return true;
    }

    @Override
    public List<DataPermissionDTO> getDataPermissionsByUserId(Long userId) {
        List<SysUserDataPermission> dataPermissions = dataPermissionRepository.findByUserId(userId);
        return dataPermissions.stream().map(this::convertToDataPermissionDTO).collect(Collectors.toList());
    }

    @Override
    public List<DataPermissionDTO> getDataPermissionsByUserIdAndEntityType(Long userId, String entityType) {
        List<SysUserDataPermission> dataPermissions = dataPermissionRepository.findByUserIdAndEntityType(userId, entityType);
        return dataPermissions.stream().map(this::convertToDataPermissionDTO).collect(Collectors.toList());
    }

    @Override
    public boolean hasPermission(Long userId, String entityType, Long resourceId) {
        return dataPermissionRepository.existsByUserIdAndEntityTypeAndResourceId(
                userId, entityType, resourceId);
    }

    @Override
    @Transactional
    public boolean assignDataPermissions(Long userId, String entityType, List<Long> resourceIds) {
        log.info("批量分配数据权限: userId={}, entityType={}, resourceIds={}",
                userId, entityType, resourceIds);

        List<SysUserDataPermission> dataPermissions = new ArrayList<>();
        for (Long resourceId : resourceIds) {
            // 检查权限是否已存在
            if (!dataPermissionRepository.existsByUserIdAndEntityTypeAndResourceId(
                    userId, entityType, resourceId)) {
                SysUserDataPermission dataPermission = new SysUserDataPermission();
                dataPermission.setUserId(userId);
                dataPermission.setEntityType(entityType);
                dataPermission.setResourceId(resourceId);
                dataPermission.setCreateTime(LocalDateTime.now());
                dataPermission.setCreateUserId(userId);
                dataPermissions.add(dataPermission);
            }
        }

        if (!dataPermissions.isEmpty()) {
            dataPermissionRepository.saveAll(dataPermissions);
        }

        log.info("批量分配数据权限成功: 分配了{}个权限", dataPermissions.size());
        return true;
    }

    @Override
    @Transactional
    public boolean revokeDataPermissions(Long userId, String entityType, List<Long> resourceIds) {
        log.info("撤销数据权限: userId={}, entityType={}, resourceIds={}",
                userId, entityType, resourceIds);

        for (Long resourceId : resourceIds) {
            dataPermissionRepository.deleteByUserIdAndEntityTypeAndResourceId(
                    userId, entityType, resourceId);
        }

        log.info("撤销数据权限成功: 撤销了{}个权限", resourceIds.size());
        return true;
    }

    @Override
    public boolean existsPermission(Long userId, String entityType, Long resourceId, String permissionType) {
        return dataPermissionRepository.existsByUserIdAndEntityTypeAndResourceId(
                userId, entityType, resourceId);
    }

    /**
     * 构建数据权限查询条件
     *
     * @param queryRequest 查询请求
     * @return 查询条件
     */
    private Specification<SysUserDataPermission> buildDataPermissionSpecification(DataPermissionQueryRequest queryRequest) {
        return (root, query, cb) -> {
            List<jakarta.persistence.criteria.Predicate> predicates = new ArrayList<>();

            // 用户ID查询
            if (queryRequest.getUserId() != null) {
                predicates.add(cb.equal(root.get("userId"), queryRequest.getUserId()));
            }

            // 实体类型查询
            if (queryRequest.getEntityType() != null) {
                predicates.add(cb.equal(root.get("entityType"), queryRequest.getEntityType()));
            }

            // 资源ID查询
            if (queryRequest.getResourceId() != null) {
                predicates.add(cb.equal(root.get("resourceId"), queryRequest.getResourceId()));
            }

            // 创建时间范围查询
            if (StringUtils.hasText(queryRequest.getCreateTimeStart())) {
                predicates.add(cb.greaterThanOrEqualTo(root.get("createTime"),
                        LocalDateTime.parse(queryRequest.getCreateTimeStart())));
            }
            if (StringUtils.hasText(queryRequest.getCreateTimeEnd())) {
                predicates.add(cb.lessThanOrEqualTo(root.get("createTime"),
                        LocalDateTime.parse(queryRequest.getCreateTimeEnd())));
            }

            return cb.and(predicates.toArray(new jakarta.persistence.criteria.Predicate[0]));
        };
    }

    /**
     * 转换数据权限实体为DTO
     *
     * @param dataPermission 数据权限实体
     * @return 数据权限DTO
     */
    private DataPermissionDTO convertToDataPermissionDTO(SysUserDataPermission dataPermission) {
        DataPermissionDTO dataPermissionDTO = new DataPermissionDTO();
        BeanUtils.copyProperties(dataPermission, dataPermissionDTO);

        // 获取用户名称
        Optional<SysUser> userOpt = userRepository.findById(dataPermission.getUserId());
        if (userOpt.isPresent()) {
            dataPermissionDTO.setUserName(userOpt.get().getRealName());
        }

        // 获取资源名称（这里需要根据实体类型动态获取，简化处理）
        dataPermissionDTO.setResourceName("资源ID: " + dataPermission.getResourceId());

        // 获取创建用户名称
        if (dataPermission.getCreateUserId() != null) {
            Optional<SysUser> createUserOpt = userRepository.findById(dataPermission.getCreateUserId());
            if (createUserOpt.isPresent()) {
                dataPermissionDTO.setCreateUserName(createUserOpt.get().getRealName());
            }
        }

        return dataPermissionDTO;
    }
}
